package sy5_Structural_Pattern.composite.safe;
import java.util.ArrayList;
import java.util.List;
/*
 * 组合模式用于处理树型结构，包含Component（抽象构件）、Leaf（叶子构件）和Composite（容器构件）三个角色。
 * 组合模式描述了如何将容器对象和叶子对象进行递归组合。
 * 通过抽象机制，可以一致地对待容器对象和叶子对象。
 * 本例是安全组合模式
 */

abstract class Component{  //角色1：抽象构件

	protected  String name;

	public Component(String name) {  //构造方法
		this.name = name;
	}

	protected  abstract void operation();  //业务方法
}

class Leaf extends Component{   //角色2：叶子构件

	public Leaf(String name) {
		super(name);  //调用父类构造方法（前提是字段name不能使用private修饰）
	}

	@Override
	protected void operation() {  //叶子构件重写的抽象方法
		System.out.println(name);  //输出叶子构件的名称
	}
}

class Composite extends Component{  //角色3：容器构件
	private List<Component> components=new ArrayList<>();  //Composite组合Component

	public Composite(String name) { //构造器
		super(name);
	}

	protected void add(Component c) {
		components.add(c);
	}

	//本例中以下两方法未使用到
	/*protected void remove(Component c) {
		components.remove(c);
	}
	protected List<Component> getChild() {
		return components;
	}*/

	@Override
	protected void operation() {   //容器构件重写的抽象方法
		System.out.println(name);  //输出容器组件名称
		for(Component c:components) {  //遍历容器组件
			c.operation();  //方法递归调用
		}
	}
}

public class Client {  //客户端

	public static void main(String[] args) {
		Composite university,computerCollege,infoEngineerCollege; //不能定义为Component类型！

		//创建根容器组件
		university = new Composite("珠海科技学院");

		//创建2个子容器组件
		computerCollege = new Composite("计算机学院");
		university.add(computerCollege);
		infoEngineerCollege = new Composite("软件工程师");
		university.add(infoEngineerCollege);

		//创建叶子组件并添加到相应的容器组件
		computerCollege.add(new Leaf("软件工程系（专业）"));
		computerCollege.add(new Leaf("网络工程系（专业）"));
		computerCollege.add(new Leaf("计算机科学与技术系（专业）"));
		infoEngineerCollege.add(new Leaf("通信工程系（专业）"));
		infoEngineerCollege.add(new Leaf("信息工程系（专业）"));

		university.operation(); //调用递归方法，遍历根容器组件
		//computerCollege.operation(); //调用递归方法，遍历特定子容器组件
		//new Leaf("计算机科学与技术系（专业）").operation(); //调用递归方法，遍历叶子组件

	}
}
